package tgc.edu.mcy.custom;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.util.StringUtils;

import com.fasterxml.jackson.databind.ObjectMapper;

public class JqgridParam {
	private Integer page;   //页号
	private Integer rows;	//每页行数
	private boolean search = false;		//是否筛选
	private String sidx;	//排序字段
	private String sord;	//排序行数
	private String searchField;		//根据那个字段查询
	private String searchOper;		//查询方式
	private String searchString;     //查询条件
	private String filters;     //多条件查询的字符串，值，
	public Integer getPage() {
		return page;
	}
	public void setPage(Integer page) {
		this.page = page;
	}
	public Integer getRows() {
		return rows;
	}
	public void setRows(Integer rows) {
		this.rows = rows;
	}
	public boolean getSearch() {
		return search;
	}
	public void setSearch(boolean search) {
		this.search = search;
	}
	public String getSidx() {
		return sidx;
	}
	public void setSidx(String sidx) {
		this.sidx = sidx;
	}
	public String getSord() {
		return sord;
	}
	public void setSord(String sord) {
		this.sord = sord;
	}	
	public String getSearchField() {
		return searchField;
	}
	public void setSearchField(String searchField) {
		this.searchField = searchField;
	}
	public String getSearchOper() {
		return searchOper;
	}
	public void setSearchOper(String searchOper) {
		this.searchOper = searchOper;
	}
	public String getSearchString() {
		return searchString;
	}
	public void setSearchString(String searchString) {
		this.searchString = searchString;
	}
	public String getFilters() {
		return filters;
	}
	public void setFilters(String filters) {
		this.filters = filters;
	}
	public Pageable buildPageable() {
		page--;
		Sort sort = Sort.by(Direction.fromString(sord), sidx);
		return PageRequest.of(page, rows, sort);    //sort排序， rows行数， page页数
	}
	//安全查询
	public Specification buildSpec() {
		Specification specification = new Specification() {

			@Override
			public Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder cb) {
				//查询结果
				Predicate predicate = null;
				//如果searchOpera运算符是eq的， 判断查询条件是否为空
				if(StringUtils.hasText(filters)) {
					ObjectMapper mapper = new ObjectMapper();
					Filters mulitFilters = null;
					try {
						mulitFilters = mapper.readValue(filters, Filters.class);
						HashSet<Predicate> rules = new HashSet<>();
						for(Rule rule: mulitFilters.getRules()) {
							Expression field = root.get(rule.getField());
							if(("eq").equals(rule.getOp())) {
								rules.add(cb.equal(field, rule.getData()));
							}else if(("ne").equals(rule.getOp())) {
								rules.add(cb.notEqual(field, rule.getData()));
							}else if(("lt").equals(rule.getOp())) {
								rules.add(cb.lessThan(field, rule.getData()));
							}else if(("le").equals(rule.getOp())) {
								rules.add(cb.lessThanOrEqualTo(field, rule.getData()));
							}else if(("gt").equals(rule.getOp())) {
								rules.add(cb.greaterThan(field, rule.getData()));
							}else if(("ge").equals(rule.getOp())) {
								rules.add(cb.greaterThanOrEqualTo(field, rule.getData()));
							}else if(("bw").equals(rule.getOp())) {
								rules.add(cb.like(field, rule.getData()+"%"));
							}else if(("bn").equals(rule.getOp())) {
								rules.add(cb.notLike(field, rule.getData()+"%"));
							}else if(("in").equals(rule.getOp())) {
								List<String> strings = new ArrayList<String>();
								split(rule.getData(), strings);
								predicate = field.in(strings);
								rules.add(predicate);
							}else if(("ni").equals(rule.getOp())) {
								List<String> strings = new ArrayList<String>();
								split(rule.getData(), strings);
								predicate = field.in(strings).not();
								rules.add(predicate);
							}else if(("ew").equals(rule.getOp())) {
								rules.add(cb.like(field, "%"+rule.getData()));
							}else if(("en").equals(rule.getOp())) {
								rules.add(cb.notLike(field, "%"+rule.getData()));
							}else if(("cn").equals(rule.getOp())) {
								rules.add(cb.like(field, "%"+rule.getData()+"%"));
							}else if(("nc").equals(rule.getOp())) {
								rules.add(cb.notLike(field, "%"+rule.getData()+"%"));
							}
						}
						if("AND".equals(mulitFilters.getGroupOp())) {
							predicate = cb.and(rules.toArray(new Predicate[rules.size()]));
						}else {
							predicate = cb.or(rules.toArray(new Predicate[rules.size()]));								
						}
					} catch (IOException e) {
						e.printStackTrace();
					}
					
				}else {
					//取出查询字段
					Expression exp = root.get(searchField);
					if("eq".equals(searchOper)) {
						predicate = cb.equal(exp, searchString);
					}
					if("ne".equals(searchOper)) {
						predicate = cb.notEqual(exp, searchString);
					}
					if("lt".equals(searchOper)) {
						predicate = cb.lessThan(exp, searchString);
					}
					if("le".equals(searchOper)) {
						predicate = cb.lessThanOrEqualTo(exp, searchString);
					}
					if("gt".equals(searchOper)) {
						predicate = cb.greaterThan(exp, searchString);
					}
					if("ge".equals(searchOper)) {
						predicate = cb.greaterThanOrEqualTo(exp, searchString);
					}
					if("bw".equals(searchOper)) {
						predicate = cb.like(exp, searchString+"%");
					}
					if("bn".equals(searchOper)) {
						predicate = cb.notLike(exp, searchString+"%");
					}
					if("in".equals(searchOper)) {
						List<String> strings = new ArrayList<String>();
						split(searchString, strings);
						predicate = exp.in(strings);
					}
					if("ni".equals(searchOper)) {
						List<String> strings = new ArrayList<String>();
						split(searchString, strings);
						predicate = exp.in(strings).not();   //在in的外面加个not()取反条件
					}
					if("ew".equals(searchOper)) {
						predicate = cb.like(exp, "%"+searchString);
					}
					if("en".equals(searchOper)) {
						predicate = cb.notLike(exp, "%"+searchString);
					}
					if("cn".equals(searchOper)) {
						predicate = cb.like(exp, "%"+searchString+"%");
					}
					if("nc".equals(searchOper)) {
						predicate = cb.notLike(exp, "%"+searchString+"%");
					}
				}
				return predicate;
			}
			
		};
		return specification;
	}
	
	public void split(String str, List<String> list) {
		if(str.contains(",") || str.contains("，")) {   //如果包含逗号的话，英文，中文
			if(str.contains("，")) {
				String[] s = StringUtils.split(str, "，");   //以，拆分字符串，     split方法第一个参数，要拆分的字符串，第二个字符串，拆分的条件
				list.add(s[0]);    //第一个先存放到list中，后面的在继续拆分
				split(s[1], list);		//回调函数
			}
			if(str.contains(",")) {
				String[] s = StringUtils.split(str, ",");   //以,拆分字符串，     split方法第一个参数，要拆分的字符串，第二个字符串，拆分的条件
				list.add(s[0]);    //第一个先存放到list中，后面的在继续拆分
				split(s[1], list);		//回调函数
			}
		}else {
			list.add(str);
		}
	}
}
